﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace thnger.ZmotionEcl1408Pro
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();

            this.updateTime = new Timer();
            this.updateTime.Interval = 200;
            this.updateTime.Tick += UpdateTime_Tick;
            this.updateTime.Start();

            //获取到所有IP
            List<string> result = motion.GetEhList();

            if (result.Count > 0)
            {
                this.cmb_IP.DataSource = result;
                this.cmb_IP.SelectedIndex = 0;
            }
        }

        #region 实时更新
        /// <summary>
        /// 实时更新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UpdateTime_Tick(object sender, EventArgs e)
        {
            if (motion.InitedOK)
            {
                //更新X轴状态
                bool StateX = motion.IsMoving(xAxis);
                this.tssl_StateX.Text = StateX ? "运行中" : "停止中";
                this.tssl_StateX.BackColor = StateX ? Color.Lime : Color.Red;
                this.tssl_StateX.ForeColor = StateX ? Color.Black : Color.White;

                //更新Y轴状态
                bool StateY = motion.IsMoving(yAxis);
                this.tssl_StateY.Text = StateY ? "运行中" : "停止中";
                this.tssl_StateY.BackColor = StateY ? Color.Lime : Color.Red;
                this.tssl_StateY.ForeColor = StateY ? Color.Black : Color.White;

                //更新Z轴状态
                bool StateZ = motion.IsMoving(zAxis);
                this.tssl_StateZ.Text = StateZ ? "运行中" : "停止中";
                this.tssl_StateZ.BackColor = StateZ ? Color.Lime : Color.Red;
                this.tssl_StateZ.ForeColor = StateZ ? Color.Black : Color.White;

                //X Y Z 轴速度
                this.tssl_VelX.Text = motion.GetVel(xAxis).ToString("f1");
                this.tssl_VelY.Text = motion.GetVel(yAxis).ToString("f1");
                this.tssl_VelZ.Text = motion.GetVel(zAxis).ToString("f1");

                //X Y Z 轴位置
                this.tssl_PosX.Text = motion.GetPos(xAxis).ToString("f2");
                this.tssl_PosY.Text = motion.GetPos(yAxis).ToString("f2");
                this.tssl_PosZ.Text = motion.GetPos(zAxis).ToString("f2");

            }
        }
        #endregion

        #region 变量属性

        private Zmotion motion = new Zmotion();

        private Timer updateTime;

        private short xAxis = 0;
        private short yAxis = 2;
        private short zAxis = 1;


        private float velMax = 0.0f;
        private float velMin = 0.0f;

        private float acc = 0.0f;
        private float dec = 0.0f;

        private float sramp = 0.0f;

        //原先速度
        private float xcreep = 0.0f;
        private float ycreep = 0.0f;
        private float zcreep = 0.0f;

        //原先距离
        private float xhomedis = 0.0f;
        private float yhomedis = 0.0f;
        private float zhomedis = 0.0f;

        //原先IO
        private int xhomeio = 24;
        private int yhomeio = 26;
        private int zhomeio = 25;


        /// <summary>
        /// 单轴运动获取轴号
        /// </summary>
        private short Axis
        {
            get { return this.rdo_X.Checked ? xAxis : this.rdo_Y.Checked ? yAxis : zAxis; }
        }
        #endregion

        #region 连接轴卡
        /// <summary>
        /// 连接正运动轴卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Connect_Click(object sender, EventArgs e)
        {
            if (this.btn_Connect.Text == "连接轴卡")
            {
                motion = new Zmotion(this.cmb_IP.Text.Trim());

                if (motion.InitCard().IsSuccess)
                {
                    this.btn_Connect.Text = "断开连接";
                    this.lbl_State.BackColor = Color.Lime;

                    MessageBox.Show("控制器连接成功", "连接提示");
                }
                else
                {
                    MessageBox.Show("控制器连接失败", "连接提示");
                }
            }
            else
            {
                if (motion.InitCard().IsSuccess)
                {
                    this.btn_Connect.Text = "连接轴卡";
                    this.lbl_State.BackColor = Color.Red;

                    MessageBox.Show("控制器断开成功", "断开提示");
                }
                else
                {
                    MessageBox.Show("控制器断开失败", "断开提示");
                }
            }
        }
        #endregion

        #region 设置参数
        /// <summary>
        /// 设置单轴参数
        /// </summary>
        private void SetParam()
        {
            velMax = Convert.ToSingle(this.num_acc.Value);
            velMin = Convert.ToSingle(this.num_dec.Value);
            acc = Convert.ToSingle(this.num_acc.Value);
            dec = Convert.ToSingle(this.num_dec.Value);
            sramp = Convert.ToSingle(this.num_sramp.Value);

            xcreep = Convert.ToSingle(this.num_creepX.Value);
            ycreep = Convert.ToSingle(this.num_creepY.Value);
            zcreep = Convert.ToSingle(this.num_creepZ.Value);

            xhomedis = Convert.ToSingle(this.num_homeDisX.Value);
            yhomedis = Convert.ToSingle(this.num_homeDisY.Value);
            zhomedis = Convert.ToSingle(this.num_homeDisZ.Value);


            //脉冲当量
            motion.unit0 = Convert.ToInt32(this.num_unit0.Value);
            motion.unit1 = Convert.ToInt32(this.num_unit1.Value);
            motion.unit2 = Convert.ToInt32(this.num_unit2.Value);

        }

        /// <summary>
        /// 设置多轴参数
        /// </summary>
        private void SetParam2()
        {
            velMax = Convert.ToSingle(this.num_acc2.Value);
            velMin = Convert.ToSingle(this.num_dec2.Value);
            acc = Convert.ToSingle(this.num_acc2.Value);
            dec = Convert.ToSingle(this.num_dec2.Value);
            sramp = Convert.ToSingle(this.num_sramp2.Value);

            //脉冲当量
            motion.unit0 = Convert.ToInt32(this.num_unit0_2.Value);
            motion.unit1 = Convert.ToInt32(this.num_unit1_2.Value);
            motion.unit2 = Convert.ToInt32(this.num_unit2_2.Value);

        }


        #endregion

        #region 单轴点动
        /// <summary>
        /// 点运动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Jog_MouseDown(object sender, MouseEventArgs e)
        {
            if (sender is Button btn)
            {
                if (btn.Tag != null && btn.Tag.ToString().Length > 0)
                {
                    if (btn.Tag.ToString().Contains(';'))
                    {
                        string[] values = btn.Tag.ToString().Split(';');

                        if (values.Length == 2)
                        {
                            //获取到轴号
                            short axis = Convert.ToInt16(values[0]);
                            //获取到方向
                            bool dir = values[1] == "1";
                            //获取设置的参数
                            SetParam();

                            var result = motion.VMove(axis, velMax, dir, velMin, acc, dec, sramp);

                            if (result.IsSuccess == false)
                            {
                                MessageBox.Show("点动运动失败" + result.ErrorMsg, "点动失败");
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 点停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Jog_MouseUp(object sender, MouseEventArgs e)
        {
            if (sender is Button btn)
            {
                if (btn.Tag != null && btn.Tag.ToString().Length > 0)
                {
                    if (btn.Tag.ToString().Contains(";"))
                    {
                        string[] values = btn.Tag.ToString().Split(';');

                        if (values.Length == 2)
                        {
                            //获取到轴号
                            short axis = Convert.ToInt16(values[0]);
                            //获取到方向
                            bool dir = values[1] == "1";
                            //获取设置的参数
                            SetParam();

                            var result = motion.StopAxis(axis);

                            if (result.IsSuccess == false)
                            {
                                MessageBox.Show("点动停止失败" + result.ErrorMsg, "点动停止");
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region 单轴运动
        /// <summary>
        /// 单轴相对运动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_MoveRelative_Click(object sender, EventArgs e)
        {
            SetParam();

            var result = motion.MoveRelative(Axis, velMax, Convert.ToSingle(this.num_distance.Value), velMin, acc, dec, sramp);

            if (result.IsSuccess == false)
            {
                MessageBox.Show("相对运动失败" + result.ErrorMsg, "相对运动");
            }
        }

        /// <summary>
        /// 单轴绝对运动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_MoveAbs_Click(object sender, EventArgs e)
        {
            SetParam();

            var result = motion.MoveAbs(Axis, velMax, Convert.ToSingle(this.num_distance.Value), velMin, acc, dec, sramp);

            if (result.IsSuccess == false)
            {
                MessageBox.Show("绝对运动失败" + result.ErrorMsg, "绝对运动");
            }
        }

        /// <summary>
        /// 单轴停止运动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StopAxis_Click(object sender, EventArgs e)
        {
            var result = motion.StopAxis(Axis);

            if (result.IsSuccess == false)
            {
                MessageBox.Show("停止运动失败" + result.ErrorMsg, "停止运动");
            }
        }

        /// <summary>
        /// 单轴位置清零
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ZeroAxis_Click(object sender, EventArgs e)
        {
            var result = motion.ZeroPos(Axis);

            if (result.IsSuccess == false)
            {
                MessageBox.Show("位置清零失败" + result.ErrorMsg, "位置清零");
            }
        }
        #endregion

        #region 单轴归零
        /// <summary>
        /// X轴回零
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ZeroX_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                SetParam();

                //通用回零
                var result = motion.ZeroAxis(xAxis, velMax, xcreep, xhomeio, xhomedis, velMin, acc, dec, sramp, 4);

                //直接回零
                //var result = motion.DirectZeroAxis(xAxis, velMax, xcreep, xhomeio, velMin, acc, dec, 4);

                if (result.IsSuccess == false)
                {
                    MessageBox.Show("X轴回零失败：" + result.ErrorMsg, "单轴回零");

                }

            });

        }

        /// <summary>
        /// Y轴回零
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ZeroY_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                SetParam();

                //通用回零
                var result = motion.ZeroAxis(yAxis, velMax, ycreep, yhomeio, yhomedis, velMin, acc, dec, sramp, 4);

                //直接回零
                //var result = motion.DirectZeroAxis(xAxis, velMax, xcreep, xhomeio, velMin, acc, dec, 4);

                if (result.IsSuccess == false)
                {
                    MessageBox.Show("Y轴回零失败：" + result.ErrorMsg, "单轴回零");

                }

            });
        }

        /// <summary>
        /// Z轴回零
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ZeroZ_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                SetParam();

                //通用回零
                var result = motion.ZeroAxis(zAxis, velMax, zcreep, zhomeio, zhomedis, velMin, acc, dec, sramp, 4);

                //直接回零
                //var result = motion.DirectZeroAxis(xAxis, velMax, xcreep, xhomeio, velMin, acc, dec, 4);

                if (result.IsSuccess == false)
                {
                    MessageBox.Show("Z轴回零失败：" + result.ErrorMsg, "单轴回零");

                }

            });
        }
        #endregion

        #region 轴全部停止及归零
        /// <summary>
        /// 一键回原点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_HomeAll_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                SetParam();

                var result = motion.ZeroAxis(zAxis, velMax, zcreep, zhomeio, zhomedis, velMin, acc, dec, sramp, 4);

                if (result.IsSuccess)
                {
                    result = motion.ZeroAxis(xAxis, velMax, xcreep, xhomeio, xhomedis, velMin, acc, dec, sramp, 4);

                    if (result.IsSuccess)
                    {
                        result = motion.ZeroAxis(yAxis, velMax, ycreep, yhomeio, yhomedis, velMin, acc, dec, sramp, 4);

                        if (result.IsSuccess)
                        {
                            MessageBox.Show("全部回零成功：", "全部回零");
                        }
                        else
                        {
                            MessageBox.Show("Y轴回零失败：" + result.ErrorMsg, "全部回零");
                            return;
                        }
                    }
                    else
                    {
                        MessageBox.Show("X轴回零失败：" + result.ErrorMsg, "全部回零");
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("Z轴回零失败：" + result.ErrorMsg, "全部回零");
                    return;
                }
            });
        }

        /// <summary>
        /// 全部停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StopAll_Click(object sender, EventArgs e)
        {
            var result = motion.StopAxis(xAxis);

            if (!result.IsSuccess)
            {
                MessageBox.Show("轴停止失败：" + result.ErrorMsg, "轴停止");
            }
        }

        #endregion

        #region
        //轴选择
        private void rdo_XY_CheckedChanged(object sender, EventArgs e)
        {
            this.num_distanceMoveZ.Enabled = !this.rdo_XY.Checked;
        }

        /// <summary>
        /// 多轴运动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StartMove_Click(object sender, EventArgs e)
        {
            SetParam2();

            //XY轴运动
            if (this.rdo_XY.Checked)
            {
                short[] axis = new short[] { xAxis, yAxis };
                float[] vel = new float[] { velMax, velMax };
                float[] pos = new float[] { Convert.ToSingle(this.num_distanceMoveX.Value), Convert.ToSingle(this.num_distanceMoveY.Value) };

                float[] velmin = new float[] { velMin, velMin };
                float[] Acc = new float[] { acc, acc };
                float[] Dec = new float[] { dec, dec };
                float[] Sramp = new float[] { sramp, sramp };

                if (rdo_Abs.Checked)
                {
                    Task.Run(() =>
                    {
                        var result = motion.Move2DAbs(axis, vel, pos, velmin, Acc, Dec, Sramp);

                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("XY运动失败：" + result.ErrorMsg, "多轴运动");
                        }
                    });
                }
                else
                {
                    Task.Run(() =>
                    {
                        var result = motion.Move2DReletive(axis, vel, pos, velmin, Acc, Dec, Sramp);
                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("XY运动失败：" + result.ErrorMsg, "多轴运动");
                        }
                    });
                }
            }
            else
            {
                short[] axis = new short[] { xAxis, yAxis, yAxis };
                float[] vel = new float[] { velMax, velMax, velMax };
                float[] pos = new float[] { Convert.ToSingle(this.num_distanceMoveX.Value), Convert.ToSingle(this.num_distanceMoveY.Value), Convert.ToSingle(this.num_distanceMoveZ.Value) };

                float[] velmin = new float[] { velMin, velMin, velMin };
                float[] Acc = new float[] { acc, acc, acc };
                float[] Dec = new float[] { dec, dec, dec };
                float[] Sramp = new float[] { sramp, sramp, sramp };

                if (rdo_Abs.Checked)
                {
                    Task.Run(() =>
                    {
                        var result = motion.Move3DAbs(axis, vel, pos, velmin, Acc, Dec, Sramp);

                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("XYZ运动失败：" + result.ErrorMsg, "多轴运动");
                        }
                    });
                }
                else
                {
                    Task.Run(() =>
                    {
                        var result = motion.Move3DReletive(axis, vel, pos, velmin, Acc, Dec, Sramp);
                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("XY运动失败：" + result.ErrorMsg, "多轴运动");
                        }
                    });
                }
            }
        }

        #endregion


        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            motion?.CloseCard();
        }

        /// <summary>
        /// 直线插补启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StartLine_Click(object sender, EventArgs e)
        {
            SetParam2();

            int[] axis;
            float[] distance;

            if (this.rdo_XY.Checked)
            {
                axis = new int[] { xAxis, yAxis, zAxis };
                distance = new float[] { Convert.ToSingle(this.num_distanceLineX.Value), Convert.ToSingle(this.num_distanceLineY.Value), Convert.ToSingle(this.num_distanceLineZ.Value) };

            }
            else
            {
                axis = new int[] { xAxis, yAxis };
                distance = new float[] { Convert.ToSingle(this.num_distanceLineX.Value), Convert.ToSingle(this.num_distanceLineY.Value) };
            }
            if (this.rdo_Abs.Checked)
            {
                Task.Run(() =>
                {
                    var result = motion.MoveLineAbs(axis, distance, velMax, acc, dec);
                    if (result.IsSuccess == false)
                    {
                        MessageBox.Show("直线插补运动失败：" + result.ErrorMsg, "直线插补");
                    }
                });
            }
            else
            {
                Task.Run(() =>
                {
                    var result = motion.MoveLineRelative(axis, distance, velMax, acc, dec);
                    if (result.IsSuccess == false)
                    {
                        MessageBox.Show("直线插补运动失败：" + result.ErrorMsg, "直线插补");
                    }
                });
            }

        }

        /// <summary>
        /// 直线插补停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StopLine_Click(object sender, EventArgs e)
        {
            var result = motion.StopAllAxis();
            if (result.IsSuccess == false)
            {
                MessageBox.Show("直线插补停止失败：" + result.ErrorMsg, "轴停止");
            }
        }

        /// <summary>
        /// 多轴控制停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_StopMove_Click(object sender, EventArgs e)
        {
            var result = motion.StopAllAxis();
            if (result.IsSuccess == false)
            {
                MessageBox.Show("多轴运动停止失败：" + result.ErrorMsg, "轴停止");
            }
        }

        /// <summary>
        /// 圆弧插补（圆心插补）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_CircleMove1_Click(object sender, EventArgs e)
        {
            SetParam2();
            if (this.rdo_XY.Checked)
            {
                int[] axis = new int[] { xAxis, yAxis, zAxis };
                float[] distance = new float[] { Convert.ToSingle(this.num_distanceCircleX.Value), Convert.ToSingle(this.num_distanceCircleY.Value), Convert.ToSingle(this.num_distanceCircleZ.Value) };
                float[] midpos = new float[] { Convert.ToSingle(this.num_MiddlePosX.Value), Convert.ToSingle(this.num_MiddlePosY.Value) };

                if (this.rdo_Abs.Checked)
                {
                    Task.Run(() =>
                    {
                        var result = motion.MoveCircleAbs(axis, distance, midpos, velMax, acc, dec, 1);
                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("圆弧插补运动失败：" + result.ErrorMsg, "圆弧插补");
                        }
                    });
                }
                else
                {
                    Task.Run(() =>
                    {
                        var result = motion.MoveCircleRelative(axis, distance, midpos, velMax, acc, dec, 1);
                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("圆弧插补运动失败：" + result.ErrorMsg, "圆弧插补");
                        }
                    });
                }
            }
            else
            {
                MessageBox.Show("目前只支持XY圆弧插补", "圆弧插补");
            }
        }

        /// <summary>
        /// 圆弧插补（中心插补）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_CircleMove2_Click(object sender, EventArgs e)
        {
            SetParam2();
            if (this.rdo_XY.Checked)
            {
                int[] axis = new int[] { xAxis, yAxis, zAxis };
                float[] distance = new float[] { Convert.ToSingle(this.num_distanceCircleX.Value), Convert.ToSingle(this.num_distanceCircleY.Value), Convert.ToSingle(this.num_distanceCircleZ.Value) };
                float[] midpos = new float[] { Convert.ToSingle(this.num_MiddlePosX.Value), Convert.ToSingle(this.num_MiddlePosY.Value) };

                if (this.rdo_Abs.Checked)
                {
                    Task.Run(() =>
                    {
                        var result = motion.MoveCircle2Abs(axis, distance, midpos, velMax, acc, dec);
                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("圆弧插补运动失败：" + result.ErrorMsg, "圆弧插补");
                        }
                    });
                }
                else
                {
                    Task.Run(() =>
                    {
                        var result = motion.MoveCircle2Relative(axis, distance, midpos, velMax, acc, dec);
                        if (result.IsSuccess == false)
                        {
                            MessageBox.Show("圆弧插补运动失败：" + result.ErrorMsg, "圆弧插补");
                        }
                    });
                }
            }
            else
            {
                MessageBox.Show("目前只支持XY圆弧插补", "圆弧插补");
            }
        }
    }
}
